const { MapService, Application, SystemLog } = require('../models');
const { AppError } = require('../middlewares/errorHandler');
const { logger } = require('../utils/logger');

class MapServiceController {
  /**
   * 创建地图服务
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async createMapService(ctx) {
    const { provider, apiKey, config, usageQuota, expiresAt } = ctx.request.body;
    const userId = ctx.state.user.id;

    // Create map service
    const mapService = await MapService.create({
      provider,
      apiKey,
      config,
      usageQuota,
      expiresAt,
      status: 'active',
      usageCount: 0
    });

    // Log the action
    await SystemLog.create({
      type: 'operation',
      action: 'create_map_service',
      userId,
      ipAddress: ctx.ip,
      userAgent: ctx.headers['user-agent'],
      description: `Map service created: ${provider}`
    });

    ctx.status = 201;
    ctx.body = {
      status: 'success',
      data: { mapService }
    };
  }

  /**
   * 更新地图服务
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async updateMapService(ctx) {
    const { id } = ctx.params;
    const { apiKey, config, usageQuota, expiresAt, status } = ctx.request.body;
    const userId = ctx.state.user.id;

    const mapService = await MapService.findByPk(id);
    if (!mapService) {
      throw new AppError(404, 'Map service not found');
    }

    // Update map service
    await mapService.update({
      apiKey,
      config,
      usageQuota,
      expiresAt,
      status
    });

    // Log the action
    await SystemLog.create({
      type: 'operation',
      action: 'update_map_service',
      userId,
      ipAddress: ctx.ip,
      userAgent: ctx.headers['user-agent'],
      description: `Map service updated: ${mapService.provider}`
    });

    ctx.body = {
      status: 'success',
      data: { mapService }
    };
  }

  /**
   * 删除地图服务
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async deleteMapService(ctx) {
    const { id } = ctx.params;
    const userId = ctx.state.user.id;

    const mapService = await MapService.findByPk(id);
    if (!mapService) {
      throw new AppError(404, 'Map service not found');
    }

    // Remove associations with applications
    await mapService.setApplications([]);
    
    await mapService.destroy();

    // Log the action
    await SystemLog.create({
      type: 'operation',
      action: 'delete_map_service',
      userId,
      ipAddress: ctx.ip,
      userAgent: ctx.headers['user-agent'],
      description: `Map service deleted: ${mapService.provider}`
    });

    ctx.body = {
      status: 'success',
      message: 'Map service deleted successfully'
    };
  }

  /**
   * 获取地图服务列表
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async getMapServices(ctx) {
    const mapServices = await MapService.findAll({
      include: [{
        model: Application,
        attributes: ['id', 'name', 'type', 'status']
      }]
    });

    ctx.body = {
      status: 'success',
      data: { mapServices }
    };
  }

  /**
   * 获取单个地图服务
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async getMapService(ctx) {
    const { id } = ctx.params;

    const mapService = await MapService.findByPk(id, {
      include: [{
        model: Application,
        attributes: ['id', 'name', 'type', 'status']
      }]
    });

    if (!mapService) {
      throw new AppError(404, 'Map service not found');
    }

    ctx.body = {
      status: 'success',
      data: { mapService }
    };
  }

  /**
   * 更新地图服务状态
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async updateMapServiceStatus(ctx) {
    const { id } = ctx.params;
    const { status } = ctx.request.body;
    const userId = ctx.state.user.id;

    const mapService = await MapService.findByPk(id);
    if (!mapService) {
      throw new AppError(404, '地图服务不存在');
    }

    // 验证状态值
    const validStatuses = ['active', 'inactive', 'maintenance', 'expired'];
    if (!validStatuses.includes(status)) {
      throw new AppError(400, '无效的状态值');
    }

    // 如果设置为过期状态，记录过期时间
    const updateData = { 
      status,
      updatedBy: userId
    };
    
    if (status === 'expired') {
      updateData.expiredAt = new Date();
    }

    await mapService.update(updateData);

    // 记录操作日志
    await SystemLog.create({
      action: 'update_map_service_status',
      operator: userId,
      target_type: 'map_service',
      target_id: id,
      details: { 
        before: mapService.status,
        after: status
      }
    });

    ctx.body = {
      status: 'success',
      data: {
        mapService
      }
    };
  }

  /**
   * 增加地图服务使用次数
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async incrementUsageCount(ctx) {
    const { id } = ctx.params;
    const userId = ctx.state.user.id;

    const mapService = await MapService.findByPk(id);
    if (!mapService) {
      throw new AppError(404, 'Map service not found');
    }

    if (mapService.status !== 'active') {
      throw new AppError(400, 'Map service is not active');
    }

    if (mapService.usageQuota && mapService.usageCount >= mapService.usageQuota) {
      throw new AppError(400, 'Usage quota exceeded');
    }

    await mapService.update({
      usageCount: mapService.usageCount + 1,
      lastUsedAt: new Date()
    });

    // Log the action
    await SystemLog.create({
      type: 'operation',
      action: 'increment_map_service_usage',
      userId,
      ipAddress: ctx.ip,
      userAgent: ctx.headers['user-agent'],
      description: `Map service ${mapService.provider} usage count incremented`
    });

    ctx.body = {
      status: 'success',
      data: { mapService }
    };
  }

  /**
   * 重置地图服务使用次数
   * @param {Object} ctx - 上下文
   * @returns {Promise<void>}
   */
  async resetUsageCount(ctx) {
    const { id } = ctx.params;
    const userId = ctx.state.user.id;

    const mapService = await MapService.findByPk(id);
    if (!mapService) {
      throw new AppError(404, 'Map service not found');
    }

    await mapService.update({
      usageCount: 0
    });

    // Log the action
    await SystemLog.create({
      type: 'operation',
      action: 'reset_map_service_usage',
      userId,
      ipAddress: ctx.ip,
      userAgent: ctx.headers['user-agent'],
      description: `Map service ${mapService.provider} usage count reset`
    });

    ctx.body = {
      status: 'success',
      data: { mapService }
    };
  }
}

module.exports = new MapServiceController(); 